package com.kkd.kkdapp.utils;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;

import com.kkd.kkdapp.db.CurUserModel;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.MeasureSpec;

/**
 * 文件与流处理工具类<br>
 * 
 * <b>创建时间</b> 2014-10-30
 * 
 * @author askzhao
 */

public final class FileUtils {
	private static final boolean DEBUG = false;

	/**
	 * 检测SD卡是否存在
	 */
	public static boolean checkSDcard() {
		return Environment.MEDIA_MOUNTED.equals(Environment
				.getExternalStorageState());
	}

	public static String generateFileName(String jid) {
		return jid + "_" + UUID.randomUUID().toString();
	}

	/**
	 * 将文件保存到本地
	 */
	public static int saveFileCache(byte[] fileData, String folderPath,
			String fileName) {
		int ret = 1;
		File folder = new File(folderPath);
		folder.mkdirs();
		File file = new File(folderPath, fileName);
		if (file != null) {
			File parent = new File(file.getParent());
			if (!parent.exists()) {
				parent.mkdirs();
			}
		}
		ByteArrayInputStream is = new ByteArrayInputStream(fileData);
		OutputStream os = null;
		if (!file.exists()) {
			try {
				file.createNewFile();
				os = new FileOutputStream(file);
				byte[] buffer = new byte[1024];
				int len = 0;
				while (-1 != (len = is.read(buffer))) {
					os.write(buffer, 0, len);
				}
				os.flush();
			} catch (Exception e) {
				ret = 0;
				// 忽略
			} finally {
				closeIO(is, os);
			}
		}
		return ret;
	}

	public static boolean saveFileToPath(String path, String fileUrl, byte[] src) {
		if (TextUtils.isEmpty(path) || TextUtils.isEmpty(fileUrl)
				|| src == null || src.length == 0)
			return false;

		File file = new File(path);
		if (!file.exists() && !file.mkdirs()) {
			return false;
		}

		String cache = null;
		// if (DEBUG) {
		// cache = path + getFileName(fileUrl);
		// } else {
		// cache = path + StringUtil.MD5Encode(fileUrl) + exName;
		// }
		cache = path + getFileName(fileUrl);
		File cacheFile = new File(cache);
		if (cacheFile.exists() && !cacheFile.delete()) {
			return false;
		}
		try {
			cacheFile.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}

		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(cacheFile);
			fos.write(src);
			fos.flush();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			try {
				if (fos != null) {
					fos.close();
					fos = null;
				}
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
		}

		return true;
	}

	public static String getFileName(String fileUrl) {
		int pos = fileUrl.lastIndexOf("/");
		if (pos == -1) {
			return fileUrl;
		} else {
			return fileUrl.substring(pos + 1);
		}
	}

	/**
	 * 从指定文件夹获取文件
	 * 
	 * @return 如果文件不存在则创建，如果无法创建文件或文件名为空则返回null
	 */
	public static File getSaveFile(String folderPath, String fileNmae) {
		File file = new File(getSavePath(folderPath) + File.separator
				+ fileNmae);
		try {
			file.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return file;
	}

	/**
	 * @Description 判断存储卡是否存在
	 * @return
	 */
	public static boolean checkSDCard() {
		if (android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED)) {
			return true;
		}

		return false;
	}

	/**
	 * 获取App根目录
	 * 
	 * @return
	 */
	public static String getKKDRootPath() {
		String path = null;
		if (checkSDCard()) {
			path = Environment.getExternalStorageDirectory().toString()
					+ File.separator
					+ com.kkd.kkdapp.Environment.KKD_APP_FILE_ROOT_PATH
					+ File.separator;

		} else {
			path = Environment.getDataDirectory().toString() + File.separator
					+ com.kkd.kkdapp.Environment.KKD_APP_FILE_ROOT_PATH
					+ File.separator;
		}

		File file = new File(path);
		if (!file.exists()) {
			file.mkdirs();
		}

		if (!file.exists()) { // 解决一部分手机将eMMC存储挂载到 /mnt/external_sd
								// 、/mnt/sdcard2 等节点
			String tmpPath = createRootDirInDevMount();
			if (tmpPath != null) {
				path = tmpPath + File.separator
						+ com.kkd.kkdapp.Environment.KKD_APP_FILE_ROOT_PATH
						+ File.separator;
			}

			file = new File(path);
			if (!file.exists()) {
				file.mkdirs();
			}

		}

		createNoMediaFile(path);

		return path;
	}

	public static String getKKDHeadIconPath() {
		String path = getKKDRootPath() + "head_icon/";

		File file = new File(path);
		if (!file.exists()) {
			file.mkdirs();
		}

		return path;
	}

	private static String createRootDirInDevMount() {
		String path = null;
		ArrayList<String> dirs = getDevMountList();
		if (dirs != null) {
			for (int i = 0; i < dirs.size(); i++) {
				String tmpPath = dirs.get(i);
				if ("/mnt/sdcard2".equals(tmpPath)
						|| "/mnt/external_sd".equals(tmpPath)) {
					path = tmpPath;
					break;
				}
			}
		}

		return path;
	}

	private static void createNoMediaFile(String dirPath) {
		String filename = ".nomedia";
		File file = new File(dirPath + filename);
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 遍历 "system/etc/vold.fstab” 文件，获取全部的Android的挂载点信息
	 * 
	 * @return
	 */
	public static ArrayList<String> getDevMountList() {
		String[] toSearch = FileUtils.readFile("/etc/vold.fstab").split(" ");
		ArrayList<String> out = new ArrayList<String>();
		for (int i = 0; i < toSearch.length; i++) {
			if (toSearch[i].contains("dev_mount")) {
				if (new File(toSearch[i + 2]).exists()) {
					out.add(toSearch[i + 2]);
				}
			}
		}
		return out;
	}

	/**
	 * 获取SD卡下指定文件夹的绝对路径
	 * 
	 * @return 返回SD卡下的指定文件夹的绝对路径
	 */
	public static String getSavePath(String folderName) {
		return getSaveFolder(folderName).getAbsolutePath();
	}

	/**
	 * 获取文件夹对象
	 * 
	 * @return 返回SD卡下的指定文件夹对象，若文件夹不存在则创建
	 */
	public static File getSaveFolder(String folderName) {
		File file = new File(Environment.getExternalStorageDirectory()
				.getAbsoluteFile()
				+ File.separator
				+ folderName
				+ File.separator);
		file.mkdirs();
		return file;
	}

	/**
	 * 输入流转byte[]<br>
	 * 
	 * <b>注意</b> 你必须手动关闭参数inStream
	 */
	public static final byte[] input2byte(InputStream inStream) {
		if (inStream == null) {
			return null;
		}
		byte[] in2b = null;
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		byte[] buff = new byte[100];
		int rc = 0;
		try {
			while ((rc = inStream.read(buff, 0, 100)) > 0) {
				swapStream.write(buff, 0, rc);
			}
			in2b = swapStream.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			closeIO(swapStream);
		}
		return in2b;
	}

	/**
	 * 把uri转为File对象
	 */
	public static File uri2File(Activity aty, Uri uri) {
		if (SystemUtils.getSDKVersion() < 11) {
			// 在API11以下可以使用：managedQuery
			String[] proj = { MediaStore.Images.Media.DATA };
			@SuppressWarnings("deprecation")
			Cursor actualimagecursor = aty.managedQuery(uri, proj, null, null,
					null);
			int actual_image_column_index = actualimagecursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			actualimagecursor.moveToFirst();
			String img_path = actualimagecursor
					.getString(actual_image_column_index);
			return new File(img_path);
		} else {
			// 在API11以上：要转为使用CursorLoader,并使用loadInBackground来返回
			String[] projection = { MediaStore.Images.Media.DATA };
			CursorLoader loader = new CursorLoader(aty, uri, projection, null,
					null, null);
			Cursor cursor = loader.loadInBackground();
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			return new File(cursor.getString(column_index));
		}
	}

	/**
	 * 复制文件
	 * 
	 * @param from
	 * @param to
	 */
	public static void copyFile(File from, File to) {
		if (null == from || !from.exists()) {
			return;
		}
		if (null == to) {
			return;
		}
		FileInputStream is = null;
		FileOutputStream os = null;
		try {
			is = new FileInputStream(from);
			if (!to.exists()) {
				to.createNewFile();
			}
			os = new FileOutputStream(to);
			copyFileFast(is, os);
		} catch (Exception e) {
			Log.i("FileUtis copyFile", e.getMessage());
		} finally {
			closeIO(is, os);
		}
	}

	public static void copyFile(String from, String to) {
		File fromFile = new File(from);
		File toFile = new File(to);

		if (null == fromFile || !fromFile.exists()) {
			return;
		}
		if (null == toFile) {
			return;
		}
		FileInputStream is = null;
		FileOutputStream os = null;
		try {
			is = new FileInputStream(fromFile);
			if (!toFile.exists()) {
				toFile.createNewFile();
			}
			os = new FileOutputStream(toFile);
			copyFileFast(is, os);
		} catch (Exception e) {
			Log.i("FileUtis copyFile", e.getMessage());
		} finally {
			closeIO(is, os);
		}
	}

	/**
	 * 快速复制文件（采用nio操作）
	 * 
	 * @param is
	 *            数据来源
	 * @param os
	 *            数据目标
	 * @throws IOException
	 */
	public static void copyFileFast(FileInputStream is, FileOutputStream os)
			throws IOException {
		FileChannel in = is.getChannel();
		FileChannel out = os.getChannel();
		in.transferTo(0, in.size(), out);
	}

	/**
	 * 关闭流
	 * 
	 * @param closeables
	 */
	public static void closeIO(Closeable... closeables) {
		if (null == closeables || closeables.length <= 0) {
			return;
		}
		for (Closeable cb : closeables) {
			try {
				if (null == cb) {
					continue;
				}
				cb.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 图片写入文件
	 * 
	 * @param bitmap
	 *            图片
	 * @param filePath
	 *            文件路径
	 * @return 是否写入成功
	 */
	public static boolean bitmapToFile(Bitmap bitmap, String filePath) {

		return bitmapToFile(bitmap, filePath, 70);
	}

	public static boolean bitmapToFile(Bitmap bitmap, String filePath,
			int quality) {
		boolean isSuccess = false;
		if (bitmap == null) {
			return isSuccess;
		}
		OutputStream out = null;
		createFile(filePath);

		try {
			out = new BufferedOutputStream(new FileOutputStream(filePath),
					8 * 1024);
			isSuccess = bitmap.compress(CompressFormat.JPEG, quality, out);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			closeIO(out);
		}
		return isSuccess;
	}

	/**
	 * 从文件中读取文本
	 * 
	 * @param filePath
	 * @return
	 */
	public static String readFile(String filePath) {
		InputStream is = null;
		try {
			is = new FileInputStream(filePath);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return inputStream2String(is);
	}

	/**
	 * 从assets中读取文本
	 * 
	 * @param name
	 * @return
	 */
	public static String readFileFromAssets(Context context, String name) {
		InputStream is = null;
		try {
			is = context.getResources().getAssets().open(name);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return inputStream2String(is);
	}

	public static void copyBigDataToSD(Context context, String from,
			String path,String strOutFileName) {
		String src = readFileFromAssets(context, from);
		saveFileToPath(path, strOutFileName, src.getBytes());
//		try {
//			InputStream myInput;
//			OutputStream myOutput = new FileOutputStream(path+strOutFileName);
//			myInput = context.getAssets().open(from);
//			byte[] buffer = new byte[1024];
//			int length = myInput.read(buffer);
//			while (length > 0) {
//				myOutput.write(buffer, 0, length);
//				length = myInput.read(buffer);
//			}
//
//			myOutput.flush();
//
//			myInput.close();
//			myOutput.close();
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}

	/**
	 * 输入流转字符串
	 * 
	 * @param is
	 * @return 一个流中的字符串
	 */
	public static String inputStream2String(InputStream is) {
		if (null == is) {
			return null;
		}
		StringBuilder resultSb = null;
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			resultSb = new StringBuilder();
			String len;
			while (null != (len = br.readLine())) {
				resultSb.append(len + "\r\n");
			}
		} catch (Exception ex) {
		} finally {
			closeIO(is);
		}
		return null == resultSb ? null : resultSb.toString();
	}

	public static boolean deleteFile(String filepath) {
		if (filepath == null || "".equals(filepath)) {
			return false;
		}
		File file = new File(filepath);
		if (file.exists() && file.isFile())
			return file.delete();
		return false;
	}

	/**
	 * This method is getting bytes from file.
	 * 
	 * @param file
	 * @return
	 */
	public static byte[] getBytesFromFile(File file) {
		byte[] ret = null;
		try {
			if (file == null) {
				return null;
			}
			FileInputStream in = new FileInputStream(file);
			ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
			byte[] b = new byte[1024];
			int n;
			while ((n = in.read(b)) != -1) {
				out.write(b, 0, n);
			}
			in.close();
			out.close();
			ret = out.toByteArray();
		} catch (IOException e) {
			e.printStackTrace(System.out);
		}
		return ret;
	}

	public static byte[] getBytesFromFile(String path) throws UnsupportedEncodingException {
		File file = new File(path);
		if(file.exists()){
			return getBytesFromFile(file);
		}else{
			return getBytesFromFile(URLDecoder.decode(path,"UTF-8"));
		}
	}

	/**
	 * 判断文件是否存在
	 */
	public static boolean isFileUrlExit(String path) {
		if (TextUtils.isEmpty(path))
			return false;
		File file = new File(path);

		return file.exists();
	}

	/**
	 * 创建文件
	 * 
	 * @param destFileName
	 * @return
	 */
	public static boolean createFile(String destFileName) {
		File file = new File(destFileName);
		if (file.exists()) {
			return false;
		}
		if (destFileName.endsWith(File.separator)) {
			return false;
		}
		// 判断目标文件所在的目录是否存在
		if (!file.getParentFile().exists()) {
			// 如果目标文件所在的目录不存在，则创建父目录
			if (!file.getParentFile().mkdirs()) {
				return false;
			}
		}
		// 创建目标文件
		try {
			if (file.createNewFile()) {
				return true;
			} else {
				return false;
			}
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 创建文件夹
	 * 
	 * @param destDirName
	 * @return
	 */

	public static boolean createDir(String destDirName) {
		File dir = new File(destDirName);
		if (dir.exists()) {
			return false;
		}
		if (!destDirName.endsWith(File.separator)) {
			destDirName = destDirName + File.separator;
		}
		// 创建目录
		if (dir.mkdirs()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 获得文件大小
	 * 
	 * @param f
	 * @return
	 */
	public static long getFileSizes(String path) {
		File f = new File(path);
		return getFileSizes(f);
	}

	public static long getFileSizes(File f) {
		long s = 0;
		if (f.exists()) {
			FileInputStream fis = null;
			try {
				fis = new FileInputStream(f);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			try {
				s = fis.available();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			try {
				f.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return s;
	}

	public static String saveToSdCard(View view, boolean isReMeasure) {

		view.buildDrawingCache();

		String floder = getKKDRootPath() + "qrcode/";
		String path = floder + CurUserModel.getCurUser().customerId
				+ "_qrcode.png";
		boolean ret = bitmapToFile(convertViewToBitmap(view, isReMeasure), path);
		if (!ret) {
			return "";
		}
		return path;
	}

	public static Bitmap convertViewToBitmap(View view, boolean isReMeasure) {
		if (isReMeasure) {

			view.measure(
					MeasureSpec.makeMeasureSpec(1000, MeasureSpec.AT_MOST),
					MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
			view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

		}
		view.setDrawingCacheEnabled(true);
		view.buildDrawingCache();
		Bitmap bitmap = view.getDrawingCache();
		return bitmap;
	}

	public static void tellMedia2Update(Context context, String path) {

		final ContentValues values = new ContentValues(2);
		values.put(MediaStore.Video.Media.MIME_TYPE, "image/jpeg");
		values.put(MediaStore.Video.Media.DATA, path);
		// Add a new record (identified by uri)
		context.getContentResolver().insert(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
		context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
				Uri.fromFile(new File(path))));

	}

	/**
	 * 放大缩小图片
	 * 
	 * @param bitmap
	 * @param w
	 * @param h
	 * @return
	 */
	public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scaleWidht = ((float) w / width);
		float scaleHeight = ((float) h / height);
		matrix.postScale(scaleWidht, scaleHeight);
		Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
				matrix, true);
		return newbmp;
	}

}